package Network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Vector;

import android.util.Log;

public class UdpClient extends Thread
{
	DatagramSocket socket = null;
	InetAddress serverInet;
	boolean go = true;
	DatagramPacket packet;
	public Vector<byte[]> mReceivedPacket = new Vector<byte[]>();
	private UdpPacket lastSentPacket;
	public UdpPacket mSendPacket;

	boolean IsInitialized = false;

	public UdpClient(String serverAddress)
	{
		Initialize(serverAddress);		
	}

	private void Initialize(String serverAddress)
	{
		try
		{
			socket = new DatagramSocket(NetworkHandler.SERVER_PORT);
			socket.setSoTimeout(100);
			
			try
			{
				serverInet = InetAddress.getByName(serverAddress);
			}
			catch (UnknownHostException e)
			{
				e.printStackTrace();
			}
		}
		catch (SocketException e)
		{
			e.printStackTrace();
		}

		IsInitialized = true;
	}
	
	public Vector<byte[]> GetReceivedPackets()
	{
		synchronized(this)
		{
			Vector<byte[]> temp = new Vector<byte[]>();
			temp.addAll(mReceivedPacket);
			mReceivedPacket.clear();
			return temp;
		}
	}
	
	public void run()
	{
		//Log.d("client", "Running");
		if(socket == null)
		{
			return;
		}
		
		while(go)
		{
			Send();
			Receive();
		}
		
		socket.close();
		
		Log.d("Client", "Exiting...");
	}
	
	public void Receive()
	{	
		byte[] data  = new byte[NetworkHandler.BYTE_SIZE];
		DatagramPacket p = new DatagramPacket(data, data.length);
		
		try
		{
			socket.receive(p);
			//Log.d("client received"," " + NetworkHandler.Deserialize(data).Pos);
			if(data != null && !mReceivedPacket.contains(data))
			{
				//synchronized(this)
				//{
					mReceivedPacket.add(data);
				//}
			}
		
			//Log.d("Client Received", "Packet size: " + data.length);
		}
		catch (IOException e)
		{
			//e.printStackTrace();
			//Log.d("Client", "Client receive timeout!");
		}
	}
	
	public void Send()
	{
		//Log.d("Client", "Starting send...");
		
		if(!IsInitialized || socket == null || mSendPacket == null || lastSentPacket == mSendPacket)
		{
			return;
		}

		byte[] data = NetworkHandler.Serialize(mSendPacket);
		//Log.d("Client Sending", "Packet size: " + data.length);
		
		packet = new DatagramPacket(data, data.length, serverInet, NetworkHandler.SERVER_PORT);
		
		try
		{
			socket.send(packet);
			
			lastSentPacket = mSendPacket;

		}
		catch (IOException e)
		{
			Log.d("Client", "Client Send Timeout");
			//e.printStackTrace();
		}
		
		//Log.d("Client Sent", "Packet size: " + packet.getLength() + " Data: " + mSendPacket.Pos.toString());
	}
}
